.TH std::ranges::dangling 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::ranges::dangling \- std::ranges::dangling

.SH Synopsis
   Defined in header <ranges>
   struct dangling;            \fI(since C++20)\fP

   dangling is a placeholder type and an empty class type, used together with the
   template aliases ranges::borrowed_iterator_t and ranges::borrowed_subrange_t.

   When some constrained algorithms that usually return an iterator or a subrange of a
   range take a particular rvalue range argument that does not model borrowed_range,
   dangling will be returned instead to avoid returning potentially dangling results.

.SH Member functions

std::ranges::dangling::dangling

   constexpr dangling() noexcept = default;   \fB(1)\fP
   template<class... Args>                    \fB(2)\fP
   constexpr dangling(Args&&...) noexcept { }

   1) dangling is trivially default constructible.
   2) dangling can be constructed from arguments of arbitrary number and arbitrary
   non-void type. The construction does not have any side-effect itself.

   In other words, after replacing the type (e.g. an iterator type) in a well-formed
   non-aggregate initialization with dangling, the resulting initialization is also
   well-formed.

.SH Example


// Run this code

 #include <algorithm>
 #include <array>
 #include <iostream>
 #include <ranges>
 #include <type_traits>
 #include <string_view>

 int main()
 {
     auto get_array_by_value = [] { return std::array{0, 1, 0, 1}; };
     auto dangling_iter = std::ranges::max_element(get_array_by_value());
     static_assert(std::is_same_v<std::ranges::dangling, decltype(dangling_iter)>);
 //  std::cout << *dangling_iter << '\\n'; // compilation error: no match for 'operator*'
                                          // (operand type is 'std::ranges::dangling')

     auto get_persistent_array = []() -> const std::array<int, 4>& {
         static constexpr std::array a{0, 1, 0, 1};
         return a;
     };
     auto valid_iter = std::ranges::max_element(get_persistent_array());
     static_assert(!std::is_same_v<std::ranges::dangling, decltype(valid_iter)>);
     std::cout << *valid_iter << ' '; // 1


     auto get_string_view = [] { return std::string_view{"alpha"}; };
     auto valid_iter2 = std::ranges::min_element(get_string_view());
         // OK: std::basic_string_view models borrowed_range
     static_assert(!std::is_same_v<std::ranges::dangling, decltype(valid_iter2)>);
     std::cout << '\\'' << *valid_iter2 << '\\'' << '\\n'; // 'a'
 }

.SH Output:

 1 'a'

.SH See also

   ranges::borrowed_iterator_t obtains iterator type or subrange type of a
   ranges::borrowed_subrange_t borrowed_range
   (C++20)                     (alias template)
                               specifies that a type is a range and iterators obtained
   ranges::borrowed_range      from an expression of it can be safely returned without
   (C++20)                     danger of dangling
                               (concept)
